package com.chinasoft.dataclean;

import org.apache.spark.sql.Dataset;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.SparkSession;

public class RFMCustomerAnalysis {

    /**RFM客户分析
     * RFM客户分析是一种常用的客户行为分析方法，通过评估客户的消费行为，帮助企业识别出高价值客户和潜在的忠诚客户。
     * RFM分析基于三个核心指标：Recency（最近一次消费时间）、Frequency（消费频率）和Monetary（消费金额），
     * 以此划分客户群体，从而优化市场策略。
     *
     * R(Recency)：用户最近一次消费距离现在的时间，R越小，用户价值越高；
     * F(Frequency)：用户在统计周期内购买商品的次数，F越大，用户价值越高；
     * M(Monetary)：用户在统计周期内的消费金额，M越大，用户价值越高。
     * 由于原数据集中没有消费金额数据，所以本次分析暂时不考虑M维度，仅考虑RF维度将现有用户分为以下四类：
     *
     * 客户类型   R    F     对应描述
     * 价值客户   高   高     F高、R高的客户，表明他们消费频率高、最近活跃高。
     * 保持客户   低   高     F高、R低的客户，表明他们消费频率高、但活跃较低。
     * 发展客户   高   低     F低、R高的客户，表明他们消费频率低、最近活跃高。需要进一步培养。
     * 挽留客户   低   低     F低、R低的客户，表明他们消费频率低，长时间没有消费，需要挽留。
     *
     * RFM客户分析的应用场景：
     * 精准营销：通过RFM分析，企业可以识别不同类型的客户，并制定个性化的营销策略。例如对高频高价值的客户进行奖励，对低频低价值的客户进行激励。
     * 客户分层管理：根据客户的RFM得分，企业可以将客户分为不同层级，提供差异化的服务。
     * 提高客户留存：通过识别那些即将流失的客户，企业可以提前采取行动，例如通过特殊优惠挽留客户。
     *
     * 思路：
     * 1. 求每个用户最后一次购买时间距离第一天的距离(天数)，以5天为分隔，≤5天的给1分，否则0分
     * 2. 求每个用户的购买次数，以2次为分隔，≥2次的给1分，否则0分
     * 3. 关联两个临时表，组合分值赋予不同的客户属性
     */
    public static void main(String[] args) {

        SparkSession spark = SparkSession.builder().appName("RFMCustomerAnalysis")
                .master("local[*]")
                .enableHiveSupport()
                .getOrCreate();

        Dataset<Row> ds = spark.sql("WITH t1 as(SELECT " +
                "  user_id,if(datediff(max(day),'2017-11-25') <= 5 , 1 , 0) as r_score " +
                "FROM  " +
                "  dwd.dwd_behavior_info " +
                "WHERE type='buy' " +
                "GROUP BY user_id), " +
                "t2 as (SELECT " +
                "  user_id,if(count(1) >= 2 , 1 , 0) as f_score " +
                "FROM  " +
                "  dwd.dwd_behavior_info " +
                "WHERE type='buy' " +
                "GROUP BY user_id) " +
                "SELECT " +
                "  user_type,count(user_id) as user_cnt " +
                "FROM ( " +
                "  SELECT " +
                "    t1.user_id, " +
                "    CASE WHEN t1.r_score=1 AND t2.f_score = 1 THEN '价值客户'  " +
                "       WHEN t1.r_score=0 AND t2.f_score = 1 THEN '保持客户'  " +
                "       WHEN t1.r_score=1 AND t2.f_score = 0 THEN '发展客户'  " +
                "       WHEN t1.r_score=0 AND t2.f_score = 0 THEN '挽留客户'  " +
                "    END AS user_type " +
                "  FROM  " +
                "    t1 JOIN t2 ON t1.user_id = t2.user_id " +
                ") " +
                "GROUP BY user_type");

        ds.write()
                .format("jdbc")
                .option("url","jdbc:mysql://douni43:3306/analyze")
                .option("dbtable","rfm_customer_analysis")
                .option("user","root")
                .option("password","123456")
                .option("driver","com.mysql.jdbc.Driver")
                .mode("overwrite")
                .save();

        spark.close();
    }
}
